import type { GameRoomPlayer } from '../data/GameRoomPlayer';
import type { GameRoomConfig } from '../data/GameRoomConfig';

export class GameRoom {
  /** 房间ID */
  private _id: string = Date.now().toString();
  /** 房间内玩家列表 */
  private _players: GameRoomPlayer[] = [];
  /** 允许房内玩家进入多个房间 */
  private _allowMultiRoom: boolean = true;
  /** 玩家是否可以加入房间 */
  private _allowPlayerJoin: boolean = true;
  /** 玩家是否可以离开房间 */
  private _allowPlayerLeave: boolean = true;
  /** 房间玩家数量上限 */
  private _maxPlayerCount: number = Infinity;
  /** 玩家 */
  /**
   * 创建房间
   * @param config 房间配置
   */
  public constructor(config: GameRoomConfig) {
    this._id = config.id || this._id;
    this._players = config.players || this._players;
    this._allowMultiRoom = config.allowMultiRoom || this._allowMultiRoom;
    this._allowPlayerJoin = config.allowPlayerJoin || this._allowPlayerJoin;
    this._allowPlayerLeave = config.allowPlayerLeave || this._allowPlayerLeave;
    this._maxPlayerCount = config.maxPlayerCount || this._maxPlayerCount;
  }

  /**
   * 销毁房间
   */
  public destroy() {}

  /**
   * 获取房间ID
   */
  public get id(): string {
    return this._id;
  }

  /**
   * 获取房间内玩家列表
   */
  public get players(): GameRoomPlayer[] {
    return this._players;
  }

  /**
   * 获取允许房内玩家是否可以进入多个房间
   */
  public get allowMultiRoom(): boolean {
    return this._allowMultiRoom;
  }
  /**
   * 获取玩家是否可以加入房间
   */
  public get allowPlayerJoin(): boolean {
    return this._allowPlayerJoin;
  }

  /**
   * 获取玩家是否可以离开房间
   */

  public get allowPlayerLeave(): boolean {
    return this._allowPlayerLeave;
  }

  /**
   * 获取房间玩家数量上限
   */

  public get maxPlayerCount(): number {
    return this._maxPlayerCount;
  }

  /**
   * 获取房间内玩家数量
   */
  public get playerCount(): number {
    return this._players.length;
  }

  /**
   * 获取房间内玩家
   * @param userId 玩家ID
   */
  private getPlayer(userId: string): GameRoomPlayer | undefined {
    return this._players.find((player) => player.userId === userId);
  }

  /**
   * 加入玩家
   * @param player 玩家
   */
  public joinPlayer(player: GameRoomPlayer): void {
    if (this.playerCount >= this.maxPlayerCount) {
      throw new Error('(GameRoomMgr) 房间已满');
    }
    if (!this.allowPlayerJoin) {
      throw new Error('(GameRoomMgr) 房间不允许玩家加入');
    }
    if (this.getPlayer(player.userId)) {
      throw new Error('(GameRoomMgr) 玩家已加入房间');
    }
    this.addPlayer(player);
  }

  /**
   * 离开玩家
   * @param userId 玩家ID
   */
  public leavePlayer(userId: string): void {
    if (!this.allowPlayerLeave) {
      throw new Error('(GameRoomMgr) 玩家不允许离开房间');
    }
    this.removePlayer(userId);
  }

  /**
   * 添加玩家
   * @param userId 玩家ID
   */
  public addPlayer(player: GameRoomPlayer) {
    this._players.push(player);
  }

  /**
   * 移除玩家
   * @param userId 玩家ID
   */
  public removePlayer(userId: string): void {
    const index = this._players.findIndex((player) => player.userId === userId);
    if (index === -1) {
      throw new Error('(GameRoomMgr) 玩家未加入房间');
    }
    this._players.splice(index, 1);
  }

  /**
   * 获取房间配置
   */
  public getConfig(): GameRoomConfig {
    return {
      id: this.id,
      players: this.players,
      allowMultiRoom: this.allowMultiRoom,
      allowPlayerJoin: this.allowPlayerJoin,
      allowPlayerLeave: this.allowPlayerLeave,
      maxPlayerCount: this.maxPlayerCount,
    };
  }

  /**
   * 清空
   */
  public clear(): void {
    this._players = [];
  }
}
